mod simple2traditional;
mod wade_giles;
use std::{fs::OpenOptions, io::BufRead};

fn get_pinyin(input: &str) -> Option<String> {
    let pinyins = {
        let mut pinyins = std::collections::HashMap::new();
        let f = OpenOptions::new().read(true).open("./pinyin.txt").unwrap();
        let reader = std::io::BufReader::new(f);
        for line in reader.lines() {
            let line = line.unwrap();
            let mut parts = line.split("	");
            let _chinese = parts.next().unwrap();
            let _pinyins = parts.next().unwrap();
            let _pinyins: Vec<String> = _pinyins.split(",").map(|x| x.to_string()).collect();
            pinyins.insert(_chinese.to_string(), _pinyins);
        }
        pinyins
    };

    let f = OpenOptions::new()
        .read(true)
        .open("./large_pinyin.txt")
        .unwrap();
    let reader = std::io::BufReader::new(f);
    let mut _last_chinese = "".to_string();
    for line in reader.lines() {
        let line = line.unwrap();
        let mut parts = line.split("	");
        let _chinese = parts.next().unwrap();
        let _chinese: String = _chinese
            .chars()
            .enumerate()
            .map(|(i, c)| {
                if c == '.' {
                    _last_chinese.chars().nth(i).unwrap()
                } else {
                    c
                }
            })
            .collect();
        _last_chinese = _chinese.clone();
        if _chinese == input {
            let mut _pinyin = "".to_string();
            // 123 -> pinyins[c1][1] + pinyins[c2][2] + pinyins[c3][3]
            let mut _pinyin: String = parts
                .next()
                .unwrap()
                .chars()
                .enumerate()
                .map(|(i, c)| {
                    let c = c.to_digit(10).unwrap() as usize;
                    pinyins
                        .get(&input.chars().nth(i).unwrap().to_string())
                        .unwrap()[c]
                        .to_string()
                        + " "
                })
                .collect();
            if _pinyin.ends_with(" ") {
                _pinyin.pop();
            }
            return Some(_pinyin);
        }
    }

    // validation
    if !input.chars().all(|c| pinyins.contains_key(&c.to_string())) {
        return None;
    }

    // default to pinyins[c][0]
    let mut input: String = input
        .chars()
        .map(|c| pinyins.get(&c.to_string()).unwrap()[0].clone() + " ")
        .collect();
    if input.ends_with(" ") {
        input.pop();
    }
    Some(input)
}

pub fn converter(input: &str) -> String {
    let input = simple2traditional::converter(input, "t2s");

    let pinyin = get_pinyin(&input).unwrap_or_else(|| "".to_string());

    let wgpinyin = wade_giles::to_wade_glides(&pinyin);

    // Capitalize the first letter if it is a letter
    let mut wgpinyin = wgpinyin.chars().collect::<Vec<char>>();
    if wgpinyin.len() > 0 {
        wgpinyin[0] = wgpinyin[0].to_uppercase().next().unwrap();
    }
    wgpinyin.iter().collect()
}
